<?php


namespace Admin\Controller;


use Admin\Builder\AdminConfigBuilder;
use Admin\Builder\AdminListBuilder;
use Admin\Model\MemberModel;
use SidToken\Crontab\MiningCrontab;
use SidToken\Model\SidMinerFakebuyModel;
use SidToken\Model\SidMinerModel;
use SidToken\Model\SidMinerProductionLogModel;
use SidToken\Model\SidTransferLogModel;
use SidToken\Model\SidUserMinerModel;
use SidToken\Utils\MemberWalletUtil;
use SidToken\Utils\TrxRpc;
use User\Model\UcenterMemberModel;

class SidTokenController extends AdminController
{
    public function jsuccess($data = '', $msg = '')
    {
        $this->json(1, $msg, $data);
        exit;
    }

    public function jerror($msg = '', $ret = 10000, $data = '')
    {
        $this->json($ret, $msg, $data);
        exit;
    }

    public function json($ret = 0, $msg = '', $data = '')
    {
        header('Content-Type:application/json; charset=utf-8');
        header('Access-Control-Allow-Methods:*');
        header('Access-Control-Allow-Headers:*');
        header("Access-Control-Request-Headers:*");
        $return = array(
            'status' => $ret,
            'info' => $msg,
            'data' => $data
        );
        echo json_encode($return);
        exit;
    }

    public function index()
    {
        $Crontab = new MiningCrontab();
        $info = $Crontab->queryStatus();
        $MinerProductionModel = new SidMinerProductionLogModel();
        $poolTotalProduction = floatval($MinerProductionModel->getPoolTotalPruduction());
        $poolYesterdayProduction = floatval($MinerProductionModel->getPoolYesterdayProduction());
        $UserMiner = new SidUserMinerModel();

        $return = [
            'yesterday_out' => $poolYesterdayProduction,
            'production_pool' => $poolTotalProduction,
            'total_user_miner' => $UserMiner->where("status=1")->count(),
        ];

        if ($info['status'] == 'finish') {
            $status = "off";
        } else {
            $status = 'on';
        }
        if ($info['time'] == strtotime(date("Ymd")) && $info['status'] == 'finish') {
            $status = "disable";
        }
        $miningInfo = [
            'status' => $status
        ];
        $this->assign("data", $miningInfo);
        $this->assign("pool", $return);
        $this->assign("ip_pool", $this->loginAdminIps());
        $this->display();
    }

    public function startMining()
    {
        $url = C("SID_URL_CONFIG.apiUrl") . "/sidToken/Queue/startMining";
        $res = curlPost($url, null);
        $this->jsuccess();
    }

    public function poolConsole()
    {
        $Crontab = new MiningCrontab();
        $UserMinerModel = new SidUserMinerModel();
        $MiningCrontab = new MiningCrontab();
        $info = $Crontab->queryStatus();
        if ($info['status'] == 'finish') {
            $status = '休眠中';
            $progress = "{$info['page']}/{$info['page']}";
            $progressPercent = 100;
            $status2 = "off";
        } else {
            $totalMiner = $lists = $UserMinerModel->where("status=1 AND start_time<={$info['time']} AND end_time>={$info['time']}")->count();
            $totalPage = round($totalMiner / $MiningCrontab::QUEUE_LENGTH);

            if ($info['status'] == 'wait') {
                $status = '队列排队';
            } else {
                $status = '挖矿中';
            }
            $progress = "{$info['page']}/$totalPage";
            $progressPercent = round($info['page'] / $totalPage * 100, 2);
            $status2 = 'on';
        }

        $miningInfo = [
            'status' => $status,
            'time' => date("Y-m-d", $info['time']),
            'progress' => $progress,
            'percent' => $progressPercent,
            'status2' => $status2
        ];
        $this->assign("data", $miningInfo);
        $this->display("pool_console");
    }

    /**
     * 用户矿机列表
     * @param int $page
     * @param int $r
     * @param int $uid
     * @param string $orderSn
     */
    public function userMinerLists($page = 1, $r = 100, $uid = 0, $orderSn = "", $name = "", $status = -1)
    {
        $map = ['status' => 1];
        if ($uid) {
            $map['uid'] = $uid;
        }
        if ($orderSn) {
            $map['order_sn'] = $orderSn;
        }
        if ($name) {
            $map['name'] = ['like', "%" . $name . "%"];
        }
        if ($status >= 0) {
            $map['status'] = $status;
        }

        $UserMiner = new SidUserMinerModel();
        $lists = $UserMiner->where($map)->order("create_time DESC")->page($page, $r)->select();
        $total = $UserMiner->where($map)->count();
        foreach ($lists as &$val) {
            $val['status'] = $val['status'] == 1 ? "正常" : "已停止";
            if ($val['status'] == '正常' && $val['start_time'] > time()) {
                $val['status'] = '未开始';
            }
            $val['total_get_amount'] = floatval($val['total_get_amount']);
            $val['day_amount'] = floatval($val['day_amount']);
            $val['type'] = $val['type'] == 'buy' ? '购买' : '赠送';
        }
        $Builder = new AdminListBuilder();
        $Builder->title("用户矿机列表({$total})")
            ->setSearchPostUrl(U("userMinerLists"))->search("uid", "uid")->search("矿机编号", "order_sn")->search('矿机名称', 'name');
        $Builder->buttonDisable(U("disableUserMiner"), "停止矿机")->buttonNew(U("?status=1"), "运行中", "", "btn btn-default btn-xs")->buttonNew(U("?status=0"), "已停止", "", "btn btn-default btn-xs");
        $Builder->keyId()->keyText('uid', 'uid')->keyText('order_sn', '矿机编号')->keyText('name', '矿机')->keyText('total_get_amount', '预计总产出')->keyText('day_amount', '日产出');
        $Builder->keyCreateTime('create_time', '购买时间')->keyCreateTime('start_time', '开始时间')->keyCreateTime('end_time', '结束时间')->keyText('status', '状态')->keyText('type', '获得类别');
        $Builder->data($lists)->pagination($total, $r)->display();

    }

    /**
     *
     */
    public function minerLists()
    {
        $Miner = new SidMinerModel();
        $lists = $Miner->field("id,name `矿机名称`,price `需usd`,price_sid `需sid`,day_amount `日产量`,release_day `释放周期(天)`,limit_amount `每人限购`,left_amount `剩余(台)`,FROM_UNIXTIME(start_time,'%Y-%m-%d') `开始时间`,FROM_UNIXTIME(create_time) `创建时间`")
            ->where("status=1")->order("id DESC")->select();
        $Builder = new AdminListBuilder();
        $Builder->buttonNew(U("editMiner"));
        $Builder->buttonDelete(U("deleteMiner"));
        $colums = ['id', '矿机名称', '需usd', '需sid', '日产量', '释放周期(天)', '每人限购', '剩余(台)', '开始时间', '创建时间'];
        foreach ($colums as $colum) {
            $Builder->keyText($colum, $colum);
        }
        $Builder->keyDoActionEdit("editMiner?id=###");
        $Builder->keyDoActionEdit("fakeBuy?miner_id=###", "[ 刷矿机 ]");
        $Builder->data($lists)->display();
    }

    public function deleteMiner($ids)
    {
        !is_array($ids) && $ids = explode(',', $ids);

        $map['id'] = array('in', $ids);
        $this->forbid('SidMiner', $map);
    }

    public function editMiner($id = 0)
    {
        $model = new SidMinerModel();
        if (IS_POST) {
            $data = $_POST;
            if (floatval($data['price']) <= 0 && floatval($data['price_sid']) <= 0) {
                $this->error("usd和sid 至少1项大于0");
            }
            if ($id) {
                $ret = $model->save($data);
            } else {
                if (!$data['start_time']) {
                    $data['start_time'] = time();
                }
                $data['create_time'] = time();
                $ret = $model->add($data);
            }
            if ($ret) {
                $this->success('操作成功', U("minerLists"));
            } else {
                $this->error($model->getDbError());
            }
        } else {
            $data = [];
            if ($id) {
                $data = $model->find($id);
            }
            $Builder = new AdminConfigBuilder();
            $Builder->title("编辑矿机");
            $Builder->keyId()->keyText('name', '矿机名称')->keyText('price', '需usd')->keyText('price_sid', '需sid')->keyText('day_amount', '日产量')->keyText('release_day', '释放周期(天)')->keyText('limit_amount', '每人限购')
                ->keyText('left_amount', '剩余(台)')->keyCreateTime('start_time', '开始时间')
                ->keyTextArea('about_1', '挖矿机制')->keyTextArea('about_2', '发行总量')->keyTextArea('about_3', '说明')->keyTextArea('about_4', '开挖时间')->keyText('sort', '排序');
            $Builder->data($data)->buttonSubmit()->buttonBack()->display();

        }
    }

    public function fakeBuy($miner_id)
    {
        if (IS_POST) {
            $model = new SidMinerModel();
            $amount = $_POST['amount'];
            $miner = $model->find($miner_id);
            $FakeBuyModel = new SidMinerFakebuyModel();
            $miner['start_time'] = $miner['start_time'] > time() ? $miner['start_time'] : strtotime(date("Ymd"));
            $miner['end_time'] = $miner['start_time'] + $miner['release_day'] * 86400;
            $ret = $FakeBuyModel->fakeBuy($miner['id'], $amount, $miner['day_amount'], $miner['start_time'], $miner['end_time']);
            $this->success("操作成功", U("minerLists"));
        } else {
            $Builder = new AdminConfigBuilder();
            $Builder->title("刷矿机");
            $data['miner_id'] = $miner_id;
            $Builder->keyHidden('miner_id', '矿机ID');
            $Builder->keyText('amount', '刷数量')->data($data)->buttonSubmit()->buttonBack()->display();
        }
    }

    public function disableUserMiner($ids)
    {
        $map['id'] = array('in', $ids);
        $this->forbid('SidUserMiner', $map);
    }

    public function transferLogList($page = 1, $r = 100, $uid = 0, $type = "", $status = 0)
    {

        $map = [];
        if ($uid) {
            $map['uid'] = $uid;
        }
        if ($type) {
            $map['type'] = $type;
        }
        if (intval($status) > 0) {
            $map['status'] = $status;
        }
        $TransLogModel = new SidTransferLogModel();
        $lists = $TransLogModel->where($map)->order("create_time DESC")->page($page, $r)->select();
        foreach ($lists as &$val) {
            $val['create_time'] = date("m/d H:i:s", $val['create_time']);
            $val['status'] = $TransLogModel->statusStr($val['status']);
            $isFromOutside = getUidByAddress($val['from']) <= 0 && $val['from'] != 'inner transfer' ? true : false;
            $isToOutside = getUidByAddress($val['to']) <= 0 && $val['to'] != 'inner transfer' ? true : false;
            if ($isFromOutside && !$isToOutside) {
                $val['transfer_type'] = "充值入账";
            } else if (!$isFromOutside && !$isToOutside) {
                $val['transfer_type'] = "内部转账";
            } else {
                $val['transfer_type'] = "外部转账";
            }
        }
        $count = $TransLogModel->where($map)->order("create_time DESC")->count();
        $Builder = new AdminListBuilder();
        $Builder->title("转账记录");
        $searchType = array(array('id' => 'USDT转入', 'value' => 'USDT转入'), array('id' => 'USDT转出', 'value' => 'USDT转出'), array('id' => 'SID转入', 'value' => 'SID转入'), array('id' => 'SID转出', 'value' => 'SID转出'));
        $Builder->setSearchPostUrl(U("transferLogList"))->search("uid", 'uid')->search('类别', 'type', 'select', '', '', '', $searchType);
        $Builder->keyId();
        $colums = ['symbol', 'amount', 'txid', 'from', 'to', 'uid', 'transfer_type', 'type', 'create_time', 'reason', 'create_time', 'status'];
        foreach ($colums as $colum) {
            $Builder->keyText($colum, $colum);
        }
        $Builder->pagination($count, $r)->data($lists)->display();
    }

    /**
     * 提现请求
     * @param int $page
     * @param int $r
     * @param int $uid
     */
    public function transferApply($page = 1, $r = 50, $uid = 0)
    {
        $map['status'] = 0;
        if ($uid) {
            $map['uid'] = $uid;
        }
        $TransLogModel = new SidTransferLogModel();
        $lists = $TransLogModel->where($map)->order("create_time DESC")->page($page, $r)->select();
        foreach ($lists as &$val) {
            $val['create_time'] = date("m/d H:i:s", $val['create_time']);
            $val['status'] = $TransLogModel->statusStr($val['status']);
            $isFromOutside = getUidByAddress($val['from']) <= 0 && $val['from'] != 'inner transfer' ? true : false;
            $isToOutside = getUidByAddress($val['to']) <= 0 && $val['to'] != 'inner transfer' ? true : false;
            if ($isFromOutside && !$isToOutside) {
                $val['transfer_type'] = "充值入账";
            } else if (!$isFromOutside && !$isToOutside) {
                $val['transfer_type'] = "内部转账";
            } else {
                $val['transfer_type'] = "外部转账";
            }
        }
        $count = $TransLogModel->where($map)->order("create_time DESC")->count();
        $Builder = new AdminListBuilder();
        $Builder->title("转账记录");

        $Builder->buttonEnable(U("doTransfer"), '通过');
        $Builder->buttonDisable(U("forbidTransfer"), '拒绝');

        $Builder->keyId();
        $colums = ['symbol', 'amount', 'txid', 'from', 'to', 'uid', 'transfer_type', 'type', 'create_time', 'reason', 'create_time', 'status'];
        foreach ($colums as $colum) {
            $Builder->keyText($colum, $colum);
        }
        $Builder->pagination($count, $r)->data($lists)->display();
    }

    public function doTransfer($ids)
    {
        !is_array($ids) && $ids = explode(',', $ids);
        $TransferLog = new SidTransferLogModel();
        $resultMessage = "操作完成";
        $MemberWallet = new MemberWalletUtil();
        foreach ($ids as $id) {
            $transfer = $TransferLog->find($id);
            if ($transfer['status'] != $TransferLog::STATUS_UNCHECK) {
                continue;
            }
            $member = D("Member")->where(['wallet_address' => $transfer['to']])->find();
            if ($member) {
                $txid = time() . mt_rand(1000, 9999);
                if (strtoupper($transfer['symbol']) == 'SID') {//提现sid需扣除5sid 手续费
                    $MemberWallet->changeSid($member['uid'], 'inc', $transfer['from'], $transfer['to'], $txid, $transfer['amount'] - 5, "钱包转入", 1, true);
                } else {
                    $MemberWallet->changeUsdt($member['uid'], 'inc', $transfer['from'], $transfer['to'], $txid, $transfer['amount'], "钱包转入", 1, true);
                }
                $result = [
                    'status' => 1,
                    'data' => [
                        'txid' => time() . mt_rand(1000, 9999),
                    ]
                ];
            } else {
                $result = [
                    'status' => 1,
                    'data' => [
                        'txid' => time() . mt_rand(1000, 9999),
                    ]
                ];
            }


            if ($result['status'] == 1) {
                $TransferLog->where(['id' => $id])->save([
                    'status' => $TransferLog::STATUS_SUCCESS,
                    'txid' => $result['data']['txid']
                ]);
                $resultMessage .= "订单{$id}转币成功; ";
            } else {
                $TransferLog->where(['id' => $id])->save([
                    'txid' => time() . mt_rand(10000, 99999),
                ]);
                $resultMessage .= "订单{$id}转币失败，原因{$result['info']}; ";
            }
        }
        $this->success($resultMessage);
    }

    public function forbidTransfer($ids)
    {
        !is_array($ids) && $ids = explode(',', $ids);
        $TransferLog = new SidTransferLogModel();
        $MemberWallet = new MemberWalletUtil();
        $resultMessage = "操作完成";
        foreach ($ids as $id) {
            $transfer = $TransferLog->find($id);
            if ($transfer['status'] != $TransferLog::STATUS_UNCHECK) {
                continue;
            }
            $TransferLog->where(['id' => $id])->save([
                'status' => $TransferLog::STATUS_FAIL,
                'txid' => "reject"
            ]);
            $symbol = $transfer['symbol'];
            $amount = $transfer['amount'];
            $uid = $transfer['uid'];
            $txid = "reject";

            if (strtoupper($symbol) == 'SID') {//提现sid需扣除5sid 手续费
                $MemberWallet->changeSid($uid, 'inc', "inner transfer", "inner transfer", $txid, $amount, "拒绝提币，订单{$transfer['id']}", $TransferLog::STATUS_SUCCESS, true);
            } else {
                $MemberWallet->changeUsdt($uid, 'inc', "inner transfer", "inner transfer", $txid, $amount, "拒绝提币，订单{$transfer['id']}", $TransferLog::STATUS_SUCCESS, true);
            }

            $resultMessage .= "订单{$id}已拒绝; ";
        }
        $this->success($resultMessage);
    }


    public function mining()
    {
        $this->display();
    }

    public function assets($page = 1, $r = 40, $sort = "default", $uid = 0, $wallet_address = "")
    {
        if ($sort == "balance_sid") {
            $sortBy = "score1 DESC";
        } else if ($sort == "balance_usd") {
            $sortBy = "score2 DESC";
        } else {
            $sortBy = "uid DESC";
        }
        $map = [];
        if ($uid) {
            $map['uid'] = $uid;
        }
        if ($wallet_address) {
            $map['wallet_address'] = $wallet_address;
        }
        $Member = new MemberModel();
        $lists = $Member->where($map)->page($page, $r)->order($sortBy)->select();
        $count = $Member->where($map)->count();
        foreach ($lists as &$val) {
            $val['score1'] = floatval($val['score1']);
            $val['score2'] = floatval($val['score2']);
            $val['id'] = $val['uid'];
        }

        $Builder = new AdminListBuilder();
        $Builder->title("资产管理");
        $Builder->buttonDisable(U("disableUser"), "禁用用户");
        $Builder->buttonEnable(U("enableUser"), "恢复用户");
        $Builder->buttonNew(U("assets?sort=default"), "默认排序", [], "btn btn-ajax btn-default");
        $Builder->buttonNew(U("assets?sort=balance_sid"), "SID排序", [], "btn btn-ajax btn-default");
        $Builder->buttonNew(U("assets?sort=balance_usd"), "USD排序", [], "btn btn-ajax btn-default");
        $Builder->setSearchPostUrl(U("assets"))->search("uid", "uid")->search("地址", "wallet_address");
        $Builder->keyId()->keyText('nickname', '账户')->keyText('wallet_address', '地址')->keyText('score1', 'SID')->keyText('score2', 'USDT')->keyStatus('status')
            ->keyCreateTime('reg_time', '注册时间')
            ->keyDoActionEdit("changeBalance?uid=###", "[ 资产修改 ]")
            ->keyDoActionEdit("transferLogList?uid=###", "[ 流水 ]")
            ->data($lists)->pagination($count, $r)->display();
    }

    public function changeBalance($uid, $symbol = '', $type = '', $amount = 0)
    {
        if (IS_POST) {
            $MemberWallet = new MemberWalletUtil();
            if (!$type) {
                $this->error("请选择类别");
            }
            if ($amount <= 0) {
                $this->jerror("请输入数量");
            }
            $txid = time() . mt_rand(1000, 9999);
            if (strtoupper($symbol) == 'USDT') {
                $MemberWallet->changeUsdt($uid, $type, "inner transfer", "inner transfer", $txid, $amount, '管理员后台添加', 1, true);
            } else {
                $MemberWallet->changeSid($uid, $type, "inner transfer", "inner transfer", $txid, $amount, '管理员后台添加', 1, true);
            }
            action_log("change_balance", "Member", $txid, is_login());
            $this->success('操作完成');

        } else {
            $data = D("Member")->where(['uid' => $uid])->field("uid,score1,score2")->find();
            if (!$data) {
                $this->error("用户不存在");
            }
            $symbolSelect = array('usdt' => 'USDT', 'sid' => 'SID');
            $typeSelect = array('inc' => '增加', 'dec' => '减少');
            $Builder = new AdminConfigBuilder();
            $Builder->title("资产修改")->keyReadOnly('uid', 'uid')->keyReadOnly('score1', 'SID')->keyReadOnly('score2', 'USDT')
                ->keySelect('symbol', '币种', '', $symbolSelect)
                ->keyRadio('type', '类别', '', $typeSelect)
                ->keyText('amount', "数量")->data($data)->buttonSubmit()->buttonBack()->display();
        }
    }

    public function disableUser($ids)
    {
        !is_array($ids) && $ids = explode(',', $ids);

        $map['uid'] = array('in', $ids);
        $map1['id'] = array('in', $ids);
        $data = array('status' => 0);
        $UcenterMember = new UcenterMemberModel();
        $res = $UcenterMember->where($map1)->save($data);
        foreach ($ids as $id) {
            clean_query_user_cache($id, 'status');
        }
        if ($res === false) {
            $this->error("禁用用户表失败~");
        }
        $this->forbid('Member', $map);
    }

    public function enableUser($ids)
    {
        !is_array($ids) && $ids = explode(',', $ids);

        $map['uid'] = array('in', $ids);
        $map1['id'] = array('in', $ids);
        $data = array('status' => 1);
        $UcenterMember = new UcenterMemberModel();
        $res = $UcenterMember->where($map1)->save($data);
        foreach ($ids as $id) {
            clean_query_user_cache($id, 'status');
        }
        if ($res === false) {
            $this->error("禁用用户表失败~");
        }
        $this->resume('Member', $map);
    }
}